// Tags: Multi Backpack
#include <cstdio>

inline int max(int x, int y) { return x > y ? x : y; }
inline int min(int x, int y) { return x < y ? x : y; }

const int N = 4e4 + 5;
int n, cap, ans, tmp, f[N], q[N], num[N];

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen64("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen64("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("MultiBackpack.in", "r", stdin);
  freopen("MultiBackpack.out", "w", stdout);
#endif
#endif

  scanf("%d%d", &n, &cap);
  for (int i = 1, v, w, m; i <= n; i++) {
    scanf("%d%d%d", &w, &v, &m);
    if (v == 0) {
      ans += m * w;
      continue;
    }
    int can_use = min(m, cap / v);
    for (int j = 0; j < v; j++) {  //枚举余数
      int tot = (cap - j) / v, head = 1, tail = 0;
      for (int k = 0; k <= tot; ++k) {
        int push_in = f[j + k * v] - k * w;
        while (head <= tail && push_in >= q[tail]) tail--;
        q[++tail] = push_in;
        num[tail] = k;
        while (head <= tail && num[head] + can_use < k) ++head;
        f[j + k * v] = max(f[j + k * v], q[head] + k * w);
        tmp = max(tmp, f[j + k * v]);
      }
    }
  }
  printf("%d", tmp + ans);
  return 0;
}